home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / newsgrp / group94a.txt / 000189_icon-group-sender _Wed Jun 29 23:04:45 1994.msg < prev    next >
Internet Message Format  |  1994-08-19  |  7KB

  1. Received: by cheltenham.cs.arizona.edu; Thu, 30 Jun 1994 08:29:13 MST
  2. From: Nevin Liber <nevin@caslon>
  3. Message-Id: <199406300604.XAA09222@caslon.CS.Arizona.EDU>
  4. Subject: DaysTil.icn
  5. To: icon-group@cs.arizona.edu (Icon Group)
  6. Date: Wed, 29 Jun 1994 23:04:45 -0700 (MST)
  7. X-Mailer: ELM [version 2.4 PL23]
  8. Content-Type: text
  9. Content-Length: 5930      
  10. Status: R
  11. Errors-To: icon-group-errors@cs.arizona.edu
  12.  
  13. Here is a little program I just wrote to calculate the number of days
  14. from the current date until the date specified on the command line.  Enjoy!
  15. -- 
  16.     Nevin ":-)" Liber    nevin@cs.arizona.edu    (602) 293-2799
  17.                                                   +++ (520) after 3/95
  18.                                       office:    (602) 621-1685
  19.         Only 44 more shopping days 'til my birthday!!
  20.  
  21. ############################################################################
  22. #
  23. #    File:     DaysTil.icn
  24. #
  25. #    Subject:  Program to calculate the number of days until a given date
  26. #
  27. #    Author:   Nevin ":-)" Liber  nevin@cs.arizona.edu  (602) 293-2799
  28. #
  29. #    Date:     June 29, 1994
  30. #
  31. ###########################################################################
  32. #
  33. #   Usage:    DaysTil sMonth iDay
  34. #
  35. #   Returns:
  36. #       0   number of days written on &output
  37. #       1   Usage message on &errout (bad parameters)
  38. #
  39. #   Revision History:
  40. #       <1> njl  6/29/94 9:50 PM        First written
  41. #
  42. #   This program calculates the number of days between the current date
  43. #   and the date specified on the command line, and writes this number to
  44. #   &output.  This is useful if you want to know how many days it is
  45. #   until a birthday, wedding day, etc.
  46. #
  47. #   The date on the command line can be specified in a variety of ways.
  48. #   For instance, if you wanted to know how many days it is until
  49. #   August 12 (my birthday), you could specify it as "August 12", "Aug 12",
  50. #   "12 August", or "12 aUGuS", among others.  The match is case
  51. #   insensitive, and the arguments will be accepted as long as exactly
  52. #   one of them is an integer, and if there are exactly two arguments.
  53. #
  54. ###########################################################################
  55.  
  56.  
  57.  
  58. ############################################################################
  59. #
  60. #   NumberOfDays(sMonth, iDay, iYear) : iNumberOfDays
  61. #
  62. #   NumberOfDays() returns the number of days into iYear that sMonth/iDay
  63. #   occurs.  For instance, NumberOfDays("February", 28) returns 59, since
  64. #   it is the 59th day into any year.  Leap years from 1901 until 2099
  65. #   are taken into account.  It fails if any parameters are bad.
  66. #
  67. #   Defaults:
  68. #       sMonth  current month
  69. #       iDay    current day of the current month
  70. #       iYear   current year
  71. #
  72. ############################################################################
  73.  
  74. procedure NumberOfDays(sMonth, iDay, iYear)
  75.  
  76.     static    LMonths
  77.     static    LDays
  78.     static    sThisMonth
  79.     static    iThisDay
  80.     static    iThisYear
  81.     local    iDays
  82.     local    i
  83.  
  84.     initial {    
  85.         LMonths := [
  86.             "january",
  87.             "february",
  88.             "march",
  89.             "april",
  90.             "may",
  91.             "june",
  92.             "july",
  93.             "august",
  94.             "september",
  95.             "october",
  96.             "november",
  97.             "december"
  98.         ]
  99.  
  100.         LDays := [
  101.             31,
  102.             28,
  103.             31,
  104.             30,
  105.             31,
  106.             30,
  107.             31,
  108.             31,
  109.             30,
  110.             31,
  111.             30
  112.         ]
  113.  
  114.         &dateline ? {
  115.             &pos := find(" ") + 1
  116.             sThisMonth := tab(find(" "))
  117.             &pos +:= 1
  118.             iThisDay := integer(tab(find(",")))
  119.             &pos +:= 2
  120.             iThisYear := integer(move(4))
  121.         }
  122.     }
  123.  
  124.     /sMonth := sThisMonth
  125.     /iDay := iThisDay
  126.     /iYear := iThisYear
  127.  
  128.     sMonth := string(sMonth) | fail
  129.     iDay := integer(iDay) | fail
  130.     iYear := integer(iYear) | fail
  131.  
  132.     if 0 ~= iYear % 4 then {
  133.         LDays[2] := 28
  134.     } else {
  135.         LDays[2] := 29
  136.     }
  137.  
  138.     iDays := iDay
  139.     every i := 1 to *LMonths do {
  140.         if CaselessMatch(sMonth, LMonths[i]) then {
  141.             return iDays
  142.         }
  143.         iDays +:= LDays[i]
  144.     }
  145.  
  146. end
  147.  
  148.  
  149. ############################################################################
  150. #
  151. #   CaselessMatch(s1, s2, i1, i2) : i3  caseless match of initial string
  152. #
  153. #    CaselessMatch(s1, s2, i1, i2) produces i1 + *s1 if
  154. #   map(s1) == map(s2[i1+:*s1]) but fails otherwise.
  155. #
  156. #   This is the same as the built-in function match(), except the
  157. #   comparisons are done without regard to case.
  158. #
  159. #   Defaults:
  160. #       s2      &subject
  161. #       i1      &pos if s2 is defaulted, otherwise 1
  162. #       i2      0
  163. #
  164. #   Errors:
  165. #       101     i1 or i2 not integer
  166. #       103     s1 or s2 not string
  167. #
  168. ############################################################################
  169.  
  170. procedure CaselessMatch(s1, s2, i1, i2)
  171.  
  172.     s1 := map(string(s1))
  173.     /i1 := (/s2 & &pos)
  174.     s2 := map(string(s2) | (/s2 & &subject))
  175.  
  176.     return match(s1, s2, i1, i2)
  177.     
  178.  
  179. end
  180.  
  181.  
  182. ############################################################################
  183. #
  184. #   Usage(fErrout, iStatus)     write usage message to fErrout and exit
  185. #
  186. #   Usage(fErrout, iStatus) writes the usage message to file fErrout
  187. #   and exits with exit status code iStatus
  188. #
  189. #   Defaults:
  190. #       fErrout  &errout
  191. #       iStatus  1
  192. #
  193. ############################################################################
  194.  
  195. procedure Usage(fErrout, iStatus)
  196.  
  197.     /fErrout := &errout
  198.     iStatus := (integer(iStatus) | 1)
  199.  
  200.     write(fErrout, "Usage: DaysTil sMonth iDay")
  201.     exit(iStatus)
  202.  
  203. end
  204.  
  205.  
  206. ############################################################################
  207. #
  208. #   main(LArguments)
  209. #
  210. #    main(LArguments) checks to make sure there are two arguments, exactly
  211. #   one of which is an integer.  If so, it tries to calculate the number
  212. #   of days between the current date and the date specified, taking into
  213. #   account if the specified date occurs after today's date only in the
  214. #   following year.  On a parameter error, it writes the usage message
  215. #   to &errout and exits with status 1.  Otherwise, it writes the number
  216. #   of days to &output and exits with status 0.
  217. #
  218. ############################################################################
  219.  
  220. procedure main(LArguments)
  221.  
  222.     local    sArgument
  223.     local    sMonth
  224.     local    iDay
  225.     local    iToday
  226.     local    iNumberOfDays
  227.  
  228.  
  229.     if 2 ~= *LArguments then {
  230.         Usage()
  231.     }
  232.  
  233.     every sArgument := !LArguments do {
  234.         (iDay := integer(sArgument)) | (sMonth := sArgument)
  235.     }
  236.  
  237.     if /iDay | /sMonth then {
  238.         Usage()
  239.     }
  240.     
  241.     iToday := NumberOfDays()
  242.     iNumberOfDays := NumberOfDays(sMonth, iDay) | Usage()
  243.     if iNumberOfDays < iToday then {
  244.         iNumberOfDays := NumberOfDays("december", 31) + NumberOfDays(sMonth, iDay, integer(&date[1+:4]) + 1)
  245.     }
  246.     
  247.     write(iNumberOfDays - iToday)
  248.  
  249. end
  250.